package com.leantech.android.browser.ui.browser.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.leantech.android.browser.browser.BrowserTab
import com.leantech.android.browser.ui.browser.adapter.TabPreviewItem
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import okhttp3.internal.toImmutableList
import java.util.LinkedList

class BrowserTabViewModel : ViewModel() {

    val tabList: MutableList<BrowserTab> = LinkedList()
    var currentActiveTabIndex = -1
        private set(value) {
            field = value
            viewModelScope.launch {
                currentIndexFlow.emit(value)
            }
        }

    private val currentIndexFlow = MutableStateFlow(currentActiveTabIndex)

    val currentBackStackFlow: Flow<List<BrowserTab.BackStackItem>> =
        currentIndexFlow.flatMapLatest { index ->
            val tab = getTabAt(index)
            tab?.backStackFlow ?: flowOf(emptyList())
        }

    val currentBackStateFlow: Flow<Boolean> = currentIndexFlow.flatMapLatest { index ->
        val tab = getTabAt(index)
        tab?.backStateFlow ?: flowOf(false)
    }

    val currentForwardStateFlow: Flow<Boolean> = currentIndexFlow.flatMapLatest { index ->
        val tab = getTabAt(index)
        tab?.forwardStateFlow ?: flowOf(false)
    }

    val currentFavoriteStateFlow: Flow<Boolean> = currentIndexFlow.flatMapLatest { index ->
        val tab = getTabAt(index)
        tab?.favoriteStateFlow ?: flowOf(false)
    }

    val currentUrlFlow: Flow<Pair<String, String>> = currentIndexFlow.flatMapLatest { index ->
        val tab = getTabAt(index)
        tab?.currentUrlFlow ?: flowOf("" to "")
    }

    private val tabsFlow = MutableStateFlow<List<BrowserTab>>(emptyList())

    val previewItemFlow: Flow<List<TabPreviewItem>> = tabsFlow.flatMapLatest {
        tabsFlow.map { tabs ->
            tabs.mapIndexed { index, browserTab ->
                TabPreviewItem(
                    tabIndex = index,
                    title = browserTab.getTitle() ?: "首页",
                    favicon = browserTab.getFavicon(),
                    current = currentActiveTabIndex == index,
                    preview = browserTab.getPreview()
                )
            }
        }
    }

    val tabCountFlow = tabsFlow.map {
        it.size
    }

    fun canGoBack(): Boolean {
        return runBlocking {
            currentBackStateFlow.firstOrNull() ?: false
        }
    }

    fun reachMaxSize(): Boolean {
        return tabList.size >= 20
    }

    private fun updateTabFlow() {
        viewModelScope.launch {
            tabsFlow.emit(tabList.toImmutableList())
        }
    }

    fun addTab(tab: BrowserTab) {
        tabList.add(tab)
        currentActiveTabIndex = tabList.size - 1
        updateTabFlow()
    }

    fun getCurrentTab(): BrowserTab? = getTabAt(currentActiveTabIndex)

    fun getTabAt(index: Int): BrowserTab? {
        return tabList.getOrNull(index)
    }

    fun removeTab(index: Int): BrowserTab? {
        if (index < 0 || index >= tabList.size) return null //index out of bounds.
        val tab = tabList.removeAt(index)
        currentActiveTabIndex = tabList.size - 1
        updateTabFlow()
        return tab
    }

    fun selectTab(index: Int): Boolean {
        if (index < 0 || index >= tabList.size) return false //index out of bounds.
        currentActiveTabIndex = index
        updateTabFlow()
        return true
    }

    fun removeAll() {
        if (tabList.isEmpty()) return
        tabList.clear()
        currentActiveTabIndex = -1

        updateTabFlow()
    }


}